﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Collection.Interfaces;
using MySoft.Data;
using Collection.DbEntities;
using Collection.Entities;
using Itfort;
namespace Collection.Services
{
	public class CatalogService : ICatalogService
	{
		#region 类目相关事件

		/// <summary>
		/// 类目值插入时发生
		/// </summary>
		public event Action<Catalog> InsertToDatabase;

		/// <summary>
		/// 引发OnInsert事件
		/// </summary>
		/// <param name="catalog">类目对象</param>
		private void OnInsert(Catalog catalog)
		{
			if (this.InsertToDatabase != null)
			{
				this.InsertToDatabase(catalog);
			}
		}

		/// <summary>
		/// 类目值更新时发生该事件
		/// </summary>
		public event Action<Catalog> UpdateToDataBase;

		/// <summary>
		/// 引发类目值更新事件
		/// </summary>
		/// <param name="catalog">类目值</param>
		private void OnUpdate(Catalog catalog)
		{
			if (this.UpdateToDataBase != null)
			{
				this.UpdateToDataBase(catalog);
			}
		}
		#endregion

		#region 根属性事件相关

		/// <summary>
		/// 根属性插入数据库时发生该事件
		/// </summary>
		public event Action<Property> InsertPropertyToDatabase;

		/// <summary>
		/// 引发 InsertPropertyToDatabase事件
		/// </summary>
		/// <param name="property">根属性值</param>
		private void OnInsertProperty(Property property)
		{
			if (this.InsertPropertyToDatabase != null)
			{
				this.InsertPropertyToDatabase(property);
			}
		}

		/// <summary>
		/// 根属性更新至数据库时引发该事件
		/// </summary>
		public event Action<Property> UpdatePropertyToDatabase;

		/// <summary>
		/// 引发 UpdatePropertyToDatabase事件
		/// </summary>
		/// <param name="property">根属性值</param>
		private void OnUpdateProperty(Property property)
		{
			if (this.UpdatePropertyToDatabase != null)
			{
				this.UpdatePropertyToDatabase(property);
			}
		}

		#endregion

		#region 属性值事件相关

		/// <summary>
		/// 属性值插入时发生
		/// </summary>
		public event Action<PropertyValue> InsertPropertyValueToDatabase;

		/// <summary>
		/// 引发OnInsert事件
		/// </summary>
		/// <param name="propertyValue">属性值</param>
		private void OnInsertPropertyValue(PropertyValue propertyValue)
		{
			if (this.InsertPropertyValueToDatabase != null)
			{
				this.InsertPropertyValueToDatabase(propertyValue);
			}
		}

		/// <summary>
		/// 属性值更新时插入时发生
		/// </summary>
		public event Action<PropertyValue> UpdatePropertyValueToDataBase;

		/// <summary>
		/// 引发属性值更新事件
		/// </summary>
		/// <param name="propertyValue">属性值</param>
		private void OnUpdatePropertyValue(PropertyValue propertyValue)
		{
			if (this.UpdatePropertyValueToDataBase != null)
			{
				this.UpdatePropertyValueToDataBase(propertyValue);
			}
		}

		#endregion

		#region 类型初始化相关

		/// <summary>
		/// DB层操作接口
		/// </summary>
		private DbSession dbSession;

		/// <summary>
		/// 类目服务构造函数
		/// </summary>
		public CatalogService()
		{
			this.dbSession = new DbSession("Taobao");
		}

		#endregion

		#region 类目操作相关

		/// <summary>
		/// 获取所有的类目信息
		/// </summary>
		/// <returns>所有的类目信息</returns>
		public IList<Catalog> GetCatalogs()
		{
			return this.dbSession.From<_Catalog>().ToList().Convert2<Catalog>();
		}

		/// <summary>
		///依据类目Id 获取单个分类对象
		/// </summary>
		/// <param name="Id">类目Id</param>
		/// <returns>单个类目对象</returns>
		public Catalog GetCatalogById(long Id)
		{
			return this.dbSession.Single<_Catalog>(_Catalog._.Id == Id).Convert2<Catalog>();
		}

		#endregion

		#region 类目根属性相关
		/// <summary>
		/// 添加类目根属性数据
		/// </summary>
		/// <param name="property">根属性对象</param>
		public void AddProperty(Property property)
		{
			this.dbSession.Save<_Property>(property.Convert2<_Property>());
			this.OnInsertProperty(property);
		}

		/// <summary>
		/// 更新类目根属性数据
		/// </summary>
		/// <param name="property">根属性对象</param>
		public void UpdateProperty(Property property)
		{
			var fields = new Field[] { _Property._.Name };
			var values = new Object[] { property.Name };
			var condition = _Property._.Id == property.Id && _Property._.CatalogId == property.CatalogId;
			this.dbSession.Update<_Property>(fields, values, condition);
			this.OnUpdateProperty(property);
		}


		/// <summary>
		/// 获取一个类目的所有根属性信息
		/// </summary>
		/// <param name="catalogId">类目Id</param>
		/// <returns>该类目相关的所有根属性</returns>
		public IList<Property> GetPropertiesByCatalog(long catalogId)
		{
			return this.dbSession.From<_Property>()
				.Where(_Property._.CatalogId == catalogId).ToList()
				.Convert2<Property>();
		}

		/// <summary>
		/// 分组获取所有的属性信息
		/// </summary>
		/// <returns>属性信息</returns>
		public List<Property> GetProperties()
		{
			return this.dbSession.From<_Property>()
				.Select(_Property._.Id, _Property._.Name)
				.GroupBy(new GroupByClip(_Property._.Id, _Property._.Name)).ToList().Convert2<Property>();
			
		}

		/// <summary>
		/// 获取商品属性信息
		/// </summary>
		/// <param name="catalogId">类目Id</param>
		/// <param name="Id">淘宝的属性Id</param>
		/// <returns></returns>
		public Property GetProperty(Int64 catalogId, Int64 Id)
		{
			return this.dbSession.Single<_Property>(_Property._.Id == Id
				&& _Property._.CatalogId == catalogId).Convert2<Property>();
		}

		/// <summary>
		/// 指定类目指定的根属性数据是否已经存在
		/// </summary>
		/// <param name="catalogId">类目Id</param>
		/// <param name="propertyId">根属性Id</param>
		/// <returns>存在：true;不存在：false</returns>
		public bool HasProperty(Int64 catalogId, Int64 propertyId)
		{
			return this.dbSession.Exists<_Property>(_Property._.CatalogId == catalogId && _Property._.Id == propertyId);
		}
		#endregion

		#region 属性值相关

		/// <summary>
		/// 添加属性值数据
		/// <param name="propertyValue">属性值对象</param>
		/// </summary>
		public void AddPropertyValue(PropertyValue propertyValue)
		{
			this.dbSession.Save<_PropertyValue>(propertyValue.Convert2<_PropertyValue>());
			this.OnInsertPropertyValue(propertyValue);
		}

		/// <summary>
		/// 更新属性值
		/// </summary>
		/// <param name="propertyValue">属性值</param>
		public void UpdatePropertyValue(PropertyValue propertyValue)
		{
			var fields = new Field[] { _PropertyValue._.Name, _PropertyValue._.Alias };
			var values = new Object[] { propertyValue.Name, propertyValue.Alias };
			var condition = _PropertyValue._.CatalogId == propertyValue.CatalogId
			&& _PropertyValue._.PropertyId == propertyValue.PropertyId
			&& _PropertyValue._.Id == propertyValue.Id;
			this.dbSession.Update<_PropertyValue>(fields, values, condition);
			this.OnUpdatePropertyValue(propertyValue);
		}

		/// <summary>
		/// 检测指定的属性值是否存在
		/// </summary>
		/// <param name="propertyValue">属性值对象</param>
		/// <returns>True:存在,False:不存在</returns>
		public bool HasPropertyValue(PropertyValue propertyValue)
		{
			var condition = _PropertyValue._.CatalogId == propertyValue.CatalogId
				&& _PropertyValue._.PropertyId == propertyValue.PropertyId
				&& _PropertyValue._.Id == propertyValue.Id;
			return this.dbSession.Exists<_PropertyValue>(condition);
		}

		/// <summary>
		/// 获取属性值信息
		/// </summary>
		/// <param name="catalog">类目</param>
		/// <param name="propertyId">属性(淘宝Id)</param>
		/// <param name="propertyValueId">属性值(淘宝Id)</param>
		/// <returns>指定的属性值信息（唯一）</returns>
		public PropertyValue GetPropertyValue(long catalog, long propertyId, long propertyValueId)
		{
			var condition = _PropertyValue._.CatalogId == catalog
										&& _PropertyValue._.PropertyId == propertyId
										&& _PropertyValue._.Id == propertyValueId;
			return this.dbSession.Single<_PropertyValue>(condition).Convert2<PropertyValue>();
		}

		/// <summary>
		/// 索取指定分类指定属性的所有属性值信息
		/// </summary>
		/// <param name="catalogId">指定的类目Id</param>
		/// <param name="propertyId">指定的属性Id</param>
		/// <returns>指定分类指定属性的所有属性值信息</returns>
		public List<PropertyValue> GetPropertyValues(long catalogId, long propertyId)
		{
			return this.dbSession.From<_PropertyValue>()
				.Where(_PropertyValue._.CatalogId == catalogId && _PropertyValue._.PropertyId == propertyId)
				.ToList().Convert2<PropertyValue>();
		}

		/// <summary>
		/// 获取一个指定属性值的子属性值
		/// </summary>
		/// <returns>指定属性值的子属性值</returns>
		public List<PropertyValue> GetChildPropertyValues(PropertyValue propertyValue)
		{
			return this.dbSession.From<_PropertyValue>()
		 .Where(_PropertyValue._.Parent == propertyValue.SerialNumber)
		 .ToList().Convert2<PropertyValue>();
		}

		/// <summary>
		/// 获取指定属性的父辈属性值
		/// </summary>
		/// <param name="propertyValue">子属性对象</param>
		/// <returns>指定子属性的父辈属性对象</returns>
		public PropertyValue GetParentPropertyValue(PropertyValue propertyValue)
		{
			return this.dbSession.Single<_PropertyValue>(_PropertyValue._.SerialNumber == propertyValue.Parent).Convert2<PropertyValue>();
		}

		#endregion
	}
}
